﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Model;
using TOOLS;
namespace BLL
{
    public  class UserCenter
    {
        public static bool Register(string username, string password, int scriptId)
        {
            var dalUser = new DAL.User();
            bool result = false;
            tb_user newUser = new tb_user();
            newUser.create_time = DateTime.Now;
            newUser.expiration_time = DateTime.Now;
            newUser.super_expiration_time = DateTime.Now;
            newUser.password = password;
            newUser.script_id = scriptId;
            newUser.user_name = username;
            if (dalUser.Count(p=>p.user_name==username&&p.script_id==scriptId)>0)
            {//指定脚本的用户已经存在
                result = false;
            }
            else
            {
                result = dalUser.Add(newUser);
            }
            if (BaseBll.enabledLog)
            {
                if (result)
                {
                    BaseBll.EnLog(string.Format("注册成功：用户名:{0},脚本ID：{1}", username, scriptId));
                }
                else
                {
                    BaseBll.EnLog(string.Format("注册失败：欲注册用户名:{0},脚本ID：{1}，注：已经存在用户", username, scriptId));
                }
            }
            return result;
        }

        public static tb_user ExistUser(string username, string password, int scriptId)
        {
            var dalUser = new DAL.User();
            return dalUser.GetOne(p => username == p.user_name && password == p.password && scriptId == p.script_id);
        }

        public static tb_user Login(string username, string password, int scriptId, out string loginKey)
        {
            var dalUser = new DAL.User();
           Model.tb_user loginUser= dalUser.GetOne(p => username == p.user_name && password == p.password && scriptId == p.script_id);
            
            if (loginUser!=null)
            {
                var temp = BaseBll.loginUserList.Where(p => p.Value.loginUser.uid == loginUser.uid && p.Value.loginStatus).FirstOrDefault();
               
                if (temp.Key!=null)
                {
                    BaseBll.EnLog(string.Format("用户名:\"{0}\"多点登录，被强制下线,脚本ID：{1}", username, scriptId));
                    BaseBll.loginUserList[temp.Key].loginStatus = false;//强制下线
                }
                loginKey = Guid.NewGuid().ToString();
                BaseBll.loginUserList.Add(loginKey, new LoginInfo()
                {
                    endTime = DateTime.Now,
                    startTime = DateTime.Now,
                    loginUser = loginUser,
                    loginKey = loginKey,
                    loginStatus = true
                });
                BaseBll.EnLog(string.Format("用户名:\"{0}\"登录,脚本ID：{1}", username, scriptId));

            }
            else
            {
                loginKey = "";
            }
           
            return loginUser;
        }

        public static string Recharge(string cdkey, string loginKey)
        {
            var dalUser = new DAL.User();
            var dalCdkey = new DAL.Cdkey();
            if (BaseBll.loginUserList.ContainsKey(loginKey))
            {
                tb_user tempUser = dalUser.GetByPrimaryKey(BaseBll.loginUserList[loginKey].loginUser.uid);
                tb_cdkey tempCdkey = dalCdkey.GetOne(p => p.cdkey == cdkey);
                if (tempCdkey==null)
                {
                    BaseBll.EnLog(string.Format("uid={0},username={1}充值CDkey无效1", tempUser.uid, tempUser.user_name));
                    return "无效cdkey";
                }
                if (tempUser.script_id!=tempCdkey.script_id)
                {
                    BaseBll.EnLog(string.Format("uid={0},username={1}充值CDkey无效2", tempUser.uid, tempUser.user_name));
                    return "cdkey无效";
                }
                if (tempCdkey.is_used==true)
                {
                    BaseBll.EnLog(string.Format("uid={0},username={1}充值失败,CDkey已经被使用:{2}", tempUser.uid, tempUser.user_name, tempCdkey.cdkey));
                    return "充值失败,CDkey已经被使用";
                }
                tempCdkey.use_time = DateTime.Now;
                tempCdkey.use_user = tempUser.user_name;
                tempCdkey.use_user_id = tempUser.uid;
                tempCdkey.is_used = true;
                if (tempUser.expiration_time < DateTime.Now)
                {
                    tempUser.expiration_time = DateTime.Now.AddHours(tempCdkey.value);
                }
                else
                {
                    tempUser.expiration_time = tempUser.expiration_time.AddHours(tempCdkey.value);
                }
                dalUser.Update(tempUser);
                dalCdkey.Update(tempCdkey);
                BaseBll.loginUserList[loginKey].loginUser = tempUser;
                BaseBll.EnLog(string.Format("uid={0},username={1}成功充值{2}小时点卡", tempUser.uid, tempUser.user_name, tempCdkey.value));
                return "";
            }
            else
            {
                return "登录超时";
            }
        }

        public static string Heartbeat(string loginKey, out tb_user userEntity)
        {

            userEntity = null;
            if (BaseBll.loginUserList.ContainsKey(loginKey))
            {
                if (BaseBll.loginUserList[loginKey].loginStatus)
                {
                    BaseBll.loginUserList[loginKey].endTime = DateTime.Now;
                    userEntity = BaseBll.loginUserList[loginKey].loginUser;
                    //var oldLoginEntity = BaseBll.loginUserList.Where(p => BaseBll.loginUserList[loginKey].loginUser.uid == p.Value.loginUser.uid && !p.Value.loginStatus).ToList();
                    //if (oldLoginEntity!=null)
                    //{
                    //    foreach (var item in oldLoginEntity)
                    //    {
                    //        BaseBll.loginUserList.Remove(item.Key);
                    //        BaseBll.EnqueueLog(string.Format("uid:{0} username:{1}清除残留登录信息", BaseBll.loginUserList[loginKey].loginUser.uid, BaseBll.loginUserList[loginKey].loginUser.user_name));
                    //    }
                    //}
                    return "";
                }
                else
                {
                    BaseBll.loginUserList.Remove(loginKey);
                    return "帐号在其它地点登录，被强迫下线";
                }
            }
            else
            {
                return "登录超时";
            }


        }

        public static string ResetPassword(string oldPassword, string newPassword, string loginKey)
        {
            var dalUser = new DAL.User();
            if (BaseBll.loginUserList.ContainsKey(loginKey))
            {
                tb_user tempUser = dalUser.GetByPrimaryKey(BaseBll.loginUserList[loginKey].loginUser.uid);
                if (tempUser != null)
                {
                    if (oldPassword == tempUser.password)
                    {
                        tempUser.password = newPassword;
                        if (dalUser.Update(tempUser))
                        {
                            BaseBll.loginUserList[loginKey].loginUser = tempUser;
                            BaseBll.EnLog(string.Format("uid={0},username={1}修改密码为{2}", tempUser.uid, tempUser.user_name, tempUser.password));
                            return "";
                          
                        }
                        else
                        {
                            BaseBll.EnLog(string.Format("uid={0},username={1}修改密码失败", tempUser.uid, tempUser.user_name));
                            return "修改失败";
                        }
                    }
                    else
                    {
                        BaseBll.EnLog(string.Format("uid={0},username={1}修改密码失败,原密码错误", tempUser.uid, tempUser.user_name));
                        return "原密码错误";
                    }
                }
                else
                {
                    BaseBll.EnLog(string.Format("uid={0},username={1}修改密码失败,数据库已经不存在该用户", BaseBll.loginUserList[loginKey].loginUser.uid, BaseBll.loginUserList[loginKey].loginUser.user_name));
                    return "登录超时";
                }
               
            }
            else
            {
                BaseBll.EnLog(string.Format("登录超时修改密码"));
                return  "登录超时";
            }
        }

        public static bool Logout(string loginKey)
        {
            if (BaseBll.loginUserList.ContainsKey(loginKey))
            {
                BaseBll.EnLog(string.Format("用户名:\"{0}\"注消,脚本ID：{1}", BaseBll.loginUserList[loginKey].loginUser.user_name, BaseBll.loginUserList[loginKey].loginUser.script_id));
                return BaseBll.loginUserList.Remove(loginKey);
                
            }
            else
            {
                BaseBll.EnLog(string.Format("有用户注消失败！"));
                return false;
            }
        }

        public static List<Model.tb_user> GetUserList(Dictionary<string, string> p)
        {
           
            var dalUser = new DAL.User();
            System.Linq.Expressions.Expression<Func<Model.tb_user, bool>> where = a => true;

            if (p.ContainsKey("script_id"))
            {
                var temp = p["script_id"].ToInt();
                where.And(a => a.script_id == temp);
            }
            if (p.ContainsKey("create_time_start"))
            {
                var temp =Convert.ToDateTime( p["create_time_start"]);
                where.And(a => a.create_time>= temp);
            }
            if (p.ContainsKey("create_time_end"))
            {
                var temp = Convert.ToDateTime(p["create_time_end"]);
                where.And(a => a.create_time <= temp);
            }
            if (p.ContainsKey("expiration_time_start"))
            {
                var temp = Convert.ToDateTime(p["expiration_time_start"]);
                where.And(a => a.expiration_time >= temp);
            }
            if (p.ContainsKey("expiration_time_end"))
            {
                var temp = Convert.ToDateTime(p["expiration_time_end"]);
                where.And(a => a.expiration_time >= temp);
            }
            if (p.ContainsKey("user_name"))
            {
                var temp = p["user_name"];
                where.And(a => a.user_name == temp);
            }
            if (p.ContainsKey("user_id"))
            {
                var temp = p["user_id"].ToInt();
                where.And(a => a.uid == temp);
            }
            if (p.ContainsKey("is_online"))
            {
                if (p["is_online"]=="true")
                {
                    List<LoginInfo> loginlist= BaseBll.loginUserList.Values.ToList();
                    List<Model.tb_user> result = new List<Model.tb_user>();
                    foreach (var item in loginlist)
                    {
                        if (item.loginStatus)
                        {
                            result.Add(item.loginUser);
                        }
                    }
                    return result.Where(where.Compile()).ToList();

                }
            }
            return dalUser.GetList(where).ToList();
           
        }

        internal static bool ChangeToGeneralTime(int userId, int hour, out string msg)
        {
            DAL.User dalUser = new DAL.User();
            var cUser = dalUser.GetByPrimaryKey(userId);
            //1:2,7:3,30:3|30:2|说明
            tb_key_value conf = DataSetting.GetChangeTimeConfig(cUser.script_id);
            float bs = 0;
            Dictionary<string, string> arr = conf.value.Split('|')[1].StringToDictionary(",", ":");
            foreach (var item in arr)
            {
                if (hour/24 >= item.Key.ToInt())
                {
                    bs = item.Value.ToFloat();
                }
            }
            TimeSpan nowSuperTime = cUser.super_expiration_time > DateTime.Now ? cUser.super_expiration_time - DateTime.Now : new TimeSpan();
            if (new TimeSpan( (int)(hour),0,0) <= nowSuperTime)
            {
                cUser.super_expiration_time = cUser.super_expiration_time.AddHours(-1 * hour);
                cUser.expiration_time = cUser.expiration_time.AddHours(1 * hour * bs-hour);
               
                if (dalUser.Update(cUser))
                {
                    msg = "转换成功";
                    return true;
                }
                else
                {
                    msg = "转换失败";
                    return false;
                }
            }
            else
            {
                msg = "剩余时间不足";
                return false;
            }
        }

        internal static  bool ChangeToSuperTime(int userId, int hour, out string msg)
        {
            DAL.User dalUser = new DAL.User();
            var cUser = dalUser.GetByPrimaryKey(userId);
            //1:4,7:3,30:2|30:0.5|说明
            tb_key_value conf = DataSetting.GetChangeTimeConfig(cUser.script_id);
            float bs = 0;
            Dictionary<string, string> arr = conf.value.Split('|')[0].StringToDictionary(",", ":");
            foreach (var item in arr)
            {
                if (hour/24 >= item.Key.ToInt())
                {
                    bs = item.Value.ToFloat();
                }
            }
            TimeSpan nowGeneralTime = cUser.super_expiration_time > DateTime.Now ? cUser.expiration_time - cUser.super_expiration_time : cUser.expiration_time- DateTime.Now;
            if (new TimeSpan((int)(hour * bs),0,0) <= nowGeneralTime)
            {
                if (cUser.super_expiration_time < DateTime.Now)
                {
                    cUser.super_expiration_time = DateTime.Now.AddHours(hour);
                }
                else
                {
                    cUser.super_expiration_time = cUser.super_expiration_time.AddHours(hour);
                }
                cUser.expiration_time = cUser.expiration_time.AddHours(-1 * hour * bs + hour);
                if (dalUser.Update(cUser))
                {
                    msg = "转换成功";
                    return true;
                }
                else
                {
                    msg = "转换失败";
                    return false;
                }
               
            }
            else
            {
                msg = "剩余时间不足";
                return false;
            }
           
        }
        
    }
}
